package com.home.security.browser.shiro;

import com.home.common.utils.object.ObjectUtils;
import com.home.security.browser.auth.entity.SysAuthMenu;
import com.home.security.browser.auth.entity.SysAuthRole;
import com.home.security.browser.auth.service.AuthService;
import com.home.common.model.CurrentUser;
import com.home.security.core.constants.UserTypeConstant;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * Description: 登录/认证
 * Created by 王大宸 on 2020-11-14 2:03
 * Created with IntelliJ IDEA.
 */
public class ShiroRealm extends AuthorizingRealm {
    private static final Logger logger = LoggerFactory.getLogger(ShiroRealm.class);

    @Autowired
    private AuthService authService;

    /***
     * 功能说明：授权权限 用户进行权限验证时候Shiro会去缓存中找,如果查不到数据,会执行这个方法去查权限,并放入缓存中
     *
     * @author 王大宸
     * @date 2020/11/14 2:04
     * @param principalCollection
     * @return org.apache.shiro.authz.AuthorizationInfo
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        CurrentUser sysUser = ObjectUtils.objToClass(principalCollection.getPrimaryPrincipal(), CurrentUser.class);
        //  查询角色和权限(这里根据业务自行查询)
        List<SysAuthRole> sysRoleList = new ArrayList<>();
        List<SysAuthMenu> sysMenuList = new ArrayList<>();
        //这里可以进行授权和处理
        Set<String> rolesSet = new HashSet<>();
        Set<String> permsSet = new HashSet<>();
        permsSet.add("index");
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        if (UserTypeConstant.SUPER_ADMINISTRATOR.equals(sysUser.getType())
                || UserTypeConstant.SUPER_ADMINISTRATOR_USERNAME.equals(sysUser.getUsername())) {
            info.addRole("admin");
            info.addStringPermission("*:*:*");
        } else {
            // 获取用户ID
            String userId = sysUser.getId();
            sysRoleList = authService.getRoleByUser(userId);
            sysMenuList = authService.getMenuByUser(userId);
            for (SysAuthRole sysRole : sysRoleList) {
                rolesSet.add(sysRole.getName());
            }
            for (SysAuthMenu menu : sysMenuList) {
                permsSet.add(menu.getPerms());
            }
            //将查到的权限和角色分别传入authorizationInfo中
            info.setStringPermissions(permsSet);
            info.setRoles(rolesSet);
        }
        return info;
    }

    /***
     * 功能说明：身份认证
     *
     * @author 王大宸
     * @date 2020/11/14 2:04
     * @param authenticationToken
     * @return org.apache.shiro.authc.AuthenticationInfo
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //获取用户的输入的账号和密码
        AuthToken authToken = (AuthToken) authenticationToken;
        String username = authToken.getUsername();
        CurrentUser user = authService.login(username, authToken.getClient());
        //进行验证  用户名 密码 设置盐值
        SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
                user,
                user.getPassword(),
                ByteSource.Util.bytes(user.getSalt()),
                getName()
        );
        //验证成功开始踢人(清除缓存和Session,保证每个账号只能一个人登录)
        ShiroUtils.deleteCache(username, authToken.getClient(), true);
        return authenticationInfo;
    }
}
